今天會開始介紹flutter cookbook的內容,flutter cookbook是一連串進階技術的教學,我會先從flutter動畫開始介紹
PageRouteBuilder提供了一個Animation物件。Animation可與Tween和Curve物件一起使用以客製化過場動畫。
首先,使用PageRouteBuilder創建一個路線。PageRouteBuilder有兩個callback,一個用於構建路線的內容(pageBuilder),一個用於構建路線的轉換(transitionsBuilder)
以下範例創建了兩條路線:一條帶有“Go!”的 home 路線。按鈕,以及標題為“Page 2”的第二條路線。
import 'package:flutter/material.dart';
void main() {
  runApp(
    const MaterialApp(
      home: Page1(),
    ),
  );
}
class Page1 extends StatelessWidget {
  const Page1({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).push(_createRoute());
          },
          child: const Text('Go!'),
        ),
      ),
    );
  }
}
Route _createRoute() {
  return PageRouteBuilder(
    pageBuilder: (context, animation, secondaryAnimation) => const Page2(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return child;
    },
  );
}
class Page2 extends StatelessWidget {
  const Page2({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: const Center(
        child: Text('Page 2'),
      ),
    );
  }
}
將PageRouteBuilder設定好後要創建Tween,要使新頁面的動畫從底部往上出現,應該設定為從 Offset(0,1) 到 Offset(0, 0)
transitionsBuilder: (context, animation, secondaryAnimation, child) {
  const begin = Offset(0.0, 1.0);
  const end = Offset.zero;
  final tween = Tween(begin: begin, end: end);
  final offsetAnimation = animation.drive(tween);
  return child;
},
Flutter 有一組繼承AnimatedWidget的widget,當動畫中的值發生變化時,它們會重新rebuild並顯示。例如,SlideTransition 採用 Animation 並在動畫值發生變化時轉換其子類(使用 FractionalTranslation widget)。
transitionsBuilder: (context, animation, secondaryAnimation, child) {
  const begin = Offset(0.0, 1.0);
  const end = Offset.zero;
  final tween = Tween(begin: begin, end: end);
  final offsetAnimation = animation.drive(tween);
  return SlideTransition(
    position: offsetAnimation,
    child: child,
  );
},
Flutter 提供了一系列curve,可以隨時間調整動畫的速率。Curves 類提供了一組預定義的常用曲線。例如,Curves.easeOut使動畫快速開始並緩慢結束。
var curve = Curves.ease;
var curveTween = CurveTween(curve: curve);
使用chain()結合上述提到的兩種Tween
const begin = Offset(0.0, 1.0);
const end = Offset.zero;
const curve = Curves.ease;
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
然後通過將它傳遞給animation.drive()創建一個新的 Animation 可以提供給 SlideTransition widget
return SlideTransition(
  position: animation.drive(tween),
  child: child,
);

參考資料:
https://docs.flutter.dev/cookbook/animation/page-route-animation